<template>
    <div class="bookRead" :class="Book.bookRead.colors[setup.bookRead.theme].page">
        <transition name="bounceTop">
            <div class="bounceTop" 
                :style="Book.bookRead.colors[setup.bookRead.theme].box" 
                v-if="bounce">
                <div class="arrow-left" @click="$router.back(-1);$router.isBack = true">
                    <van-icon name="arrow-left" size="30"/>
                </div>
                <div class="right">
                    <div>
                        <van-icon name="audio" @click="startReadFiction" size="30"/>
                    </div>
                    <div>
                        <van-icon name="down" size="30"/>
                    </div>
                    <div @click="$router.push('/bookDetail?id=' + $route.query.fid)">
                        <van-icon name="weapp-nav" size="28"/>
                    </div>
                </div>
                <div class="addBookshelfRead"
                :style="Book.bookRead.colors[setup.bookRead.theme].addBookShele"
                v-if="!isBookshelf" @click="addBookshelf(addShelfSuccess, 'fiction_shelf')">
                    加入书架
                </div>
            </div>
        </transition>

        <bookPage :chapter="contents[chapterNum] || {}" @upperPage="upperPage" @nextPage="nextPage"
        @clickPage="clickPage" ref="bookPage" @afterInit="afterInit"
        :isSpeechTTs="isSpeechTTs"
        :listenIndex="listenIndex"
        @updateBookPoi="updateBookPoi"/>


        <transition name="bounceBottom">
            <div class="bounceBottom"
                :style="Book.bookRead.colors[setup.bookRead.theme].box"
                v-if="bounce">
                <div class="top">
                    <span @click="() => { upperPage(); this.type = '' }">上一章</span>
                    <div>
                        <van-slider v-model="chapterNum"
                        :max="list.length - 1"
                        button-size="20"
                        inactive-color="var(--bookReadTextColor)"
                        active-color="var(--bookReadTextColor)"
                        @change="change"
                        />
                    </div>
                    <span @click="nextPage">下一章</span>
                </div>
                <div class="bottom">
                    <div @click="onShow">目录</div>
                    <div @click="$router.push('/bookReadSetting')">设置</div>
                </div>
            </div>
        </transition>

        <!-- 目录 -->
        <van-popup v-model="show"
        style="width: 70%;height: 100%;"
        position="left">
            <div class="fictionChaptersTitle">
                目录
            </div>
            <div class="fictionChapters" id="scrollChapters">
                <fictionChapters @replace="replace" v-if="show" :fictionChapters="list" :chapterNum="chapterNum" :contents="contents"/>
            </div>
        </van-popup>

        <div class="TTS" v-if="isSpeechTTs != 0" @click="PlayOrPause">
            <div class="TTSboxBottom" v-show="isSpeechTTs == 2" @click.stop>

                <div class="TTS-line">
                    <div>语速</div>
                    <van-slider v-model="speech.rate"
                    :max="15"
                    :min="0"
                    button-size="20"
                    inactive-color="#999"
                    active-color="#fff"
                    @change="resdTTs"
                    />
                </div>

                <div class="TTS-line" v-if="speech.pers">
                    <div class="pers">
                        <div v-for="(item, index) in speech.pers" :key="index"
                        :class="{active : speech.per == item.value}"
                        @click="resdTTs(speech.per = item.value)"
                        >{{ item.key }}</div>
                    </div>
                </div>

                <div class="TTSend" @click="cancelSpeech">退出朗读</div>
            </div>
        </div>

        <LoadAnimation :load="Load"/>
    </div>
</template>

<script>
import { getFictionContentList } from '@/api/fictionContent'
import { getFictionChapterList } from '@/api/fictionChapter'
import { getFictionShelfAdd } from '@/api/fictionShelf'
import { mapState, mapMutations } from 'vuex'
import fictionChapters from '@/components/book/fictionChapters.vue'
import bookPage from './bookPage2.vue'
import { debounce } from '@/utils/Tool'
import TTS from '@/utils/tts'
export default {
    components : {
        bookPage,
        fictionChapters,
    },
    data() {
        return {
            list : [],
            contents : {},
            fid : 0,
            cid : 0,
            chapterNum : 0,
            show : false,
            bounce : false,
            type : 'init',
            isBookshelf : false,
            Load : false,
            Lock : false,

            // 语言服务
            speech: null,
            isSpeechTTs : 0,
            listenIndex : -1
        }
    },
    computed : {
        ...mapState(['Book', 'setup'])
    },
    created(){

        // 开启防抖
        this.addBookshelf = debounce(this.addBookshelf, 1500)
        this.addBookshelf(null, 'foot')

        // 初始化语言朗读
        this.speechInit()

        this.chapterNum = parseInt(this.$route.query.chapterNum)
        this.fid = parseInt(this.$route.query.fid)
        this.cid = parseInt(this.$route.query.cid)
        this.getChapter()

        this.initEvent()
        
        this.createContent()
    },
    beforeDestroy(){
        this.endEvent()
        this.cancelSpeech()
    },
    methods : {
        
        ...mapMutations(['getFictionShelfList']),

        volumeup(KeyEvent){
            this.$refs.bookPage.$emit('pageUpperPage')
        },
        volumedown(KeyEvent){
            this.$refs.bookPage.$emit('pageNextPage')
        },

        // 初始化语言朗读
        speechInit(type = 'TTS') {
            try{
                this.speech = new TTS[type]()
                this.speech.setLanguage("zh-CN");
                this.speech.init().then(() => {});
            }catch(e){
                this.$toast('语言朗读初始化失败')
            }
        },

        // 朗读
        speakTtsSpeech(list) {
            if (this.isSpeechTTs == 2) {
                this.isSpeechTTs = 1
                this.speech.resume();
            }else if (this.isSpeechTTs == 0) {
                return
            }
            let self = this
            this.speech.speak({
                text : self.listenIndex == -1 ? list.fictionChapter.chapterName : list.contents[self.listenIndex],
                listeners : {
                    onend(){
                        self.listenIndex++
                        if (self.listenIndex < list.contents.length) {
                            self.speakTtsSpeech(list)
                            self.$refs.bookPage.$emit('checkListenPage')
                        }else{
                            if(self.nextPage()){
                                self.listenIndex = -1
                                self.speakTtsSpeech(self.contents[self.chapterNum])
                            }
                        }
                    }
                },
            })
        },

        // 配置修改，重置朗读
        resdTTs(){
            this.speech.cancel();
            this.speakTtsSpeech(this.contents[this.chapterNum])
        },

        // 切换
        PlayOrPause(){
            if (this.isSpeechTTs == 2) {
                this.speakTtsSpeech(this.contents[this.chapterNum])
            }else{
                this.pauseSpeech()
            }
        },

        // 暂停朗读
        pauseSpeech(){
            this.speech.pause()
            this.isSpeechTTs = 2
        },

        // 关闭朗读
        cancelSpeech(){
            this.speech.cancel();
            this.isSpeechTTs = 0
            this.initEvent()
        },

        // 初始化事件
        initEvent(){
            let self = this
            try{
                if(this.setup.bookRead.volumeFlipping){
                    // 关闭默认音量键功能
                    plus.key.setVolumeButtonEnabled(false);
                    //音量+按键监听
                    plus.key.addEventListener('volumeupbutton', self.volumeup);
                    //音量-按键监听
                    plus.key.addEventListener('volumedownbutton', self.volumedown);
                }
            }catch(e){}
        },

        // 关闭事件
        endEvent(){
            let self = this
            try{
                // 开启默认音量键功能
                plus.key.setVolumeButtonEnabled(true);
                //音量+按键监听
                plus.key.removeEventListener('volumeupbutton', self.volumeup);
                //音量-按键监听
                plus.key.removeEventListener('volumedownbutton', self.volumedown);

            }catch(e){}
        },


        // 开启听小说模式
        startReadFiction(){
            if (this.isSpeechTTs != 0) {
                return
            }
            let self = this
            this.bounce = false
            this.isSpeechTTs = 1
            this.$refs.bookPage.$emit('getListenPage', (i) => {
                self.listenIndex = i || -1
                let list = self.contents[self.chapterNum]
                self.speakTtsSpeech(list)
            })
            this.endEvent()
        },

        // 打开目录
        onShow(){
            this.show = true
        },
                                                                                                                                                                             
        //进度变化且结束拖动后触发
        change(){
            this.replace()
        },

        //保存当前阅读进度
        updateBookPoi(){
            localStorage.setItem('bookRead:fid:' + this.fid, this.Book.bookRead.poi)
        },

        // 跳转章节
        replace(chapterNum){
            this.show = false
            this.bounce = false
            this.chapterNum = chapterNum ? chapterNum : this.chapterNum
            this.type = ''
            this.getContext()
            this.addBookshelf(null, 'foot')
        },

        // 初始化小说当前内容，只在第一次创建页面时执行
        createContent(){
            this.Lock = true
            this.Load = true
            this.getWord(this.chapterNum, res => {
                if(res.code == 200){
                    this.$refs.bookPage.$emit('init', res.data)
                }
                this.Load = false
                this.Lock = false
            }, this.cid)
        },

        //获取章节当前之后的内容
        getContext(){

            if(this.contents[this.chapterNum]){
                this.$refs.bookPage.$emit('init', this.contents[this.chapterNum])
            }else if(!this.Load){
                this.Lock = true
                this.Load = true
                this.getWord(this.chapterNum, res => {
                    if(res.code == 200){
                        this.$refs.bookPage.$emit('init', res.data)
                    }
                    this.Load = false
                    this.Lock = false
                })
            }
            
            for (let index = this.chapterNum + 1; index < this.list.length; index++) {
                if(index > this.chapterNum + 4){
                    break;
                }
                if(!this.contents[index]){
                    this.getWord(index)
                }
            }

        },

        // 获取内容
        getWord(index, fn, id){
            getFictionContentList(id || this.list[index].fictionChapterId).then(res => {
                if(res.code == 200){
                    this.contents[index] = res.data
                }
                if(typeof fn == 'function'){
                    fn(res)
                }
            })
        },

        //获取小说目录
        getChapter(){
            getFictionChapterList(this.fid).then(res => {
                if(res.code == 200){
                    this.list = res.data.fictionChapters
                    this.isBookshelf = res.data.isBookshelf
                    this.getContext()
                }
            })
        },

        // 点击中心页面时
        clickPage(){
            this.bounce = !this.bounce
        },
        
        // 小说page页面初始化完成时，设置当前阅读位置
        afterInit(){
            if(this.type == 'init'){
                var value = localStorage.getItem('bookRead:fid:' + this.fid)
                this.Book.bookRead.poi = parseInt(value) || 0
            }else if(this.type == 'upperPage'){
                this.Book.bookRead.poi = this.Book.bookRead.pageLength - 1
            }else if(this.type == 'nextPage'){
                this.Book.bookRead.poi = 0
            }
            this.type = ''
            this.updateBookPoi()
        },

        // 上一章
        upperPage(fn){
            if(this.Lock){
                return false
            }
            if(this.chapterNum > 0){
                this.chapterNum--
                if(typeof fn == 'function'){
                    fn()
                }
                this.type = 'upperPage'
                this.getContext()
                this.addBookshelf(null, 'foot')
                return true
            }else{
                this.$toast('已经是第一页啦')
                return false
            }
        },

        // 下一章
        nextPage(fn){
            if(this.Lock){
                return false
            }
            if(this.chapterNum + 1 != this.list.length){
                this.chapterNum++
                if(typeof fn == 'function'){
                    fn()
                }
                this.getContext()
                this.addBookshelf(null, 'foot')
                return true
            }else{
                this.$toast('已经最新章节啦')
                return false
            }
        },

        addShelfSuccess(){
            this.isBookshelf = true
        },

        //添加到书架
        addBookshelf(fn, type){

            getFictionShelfAdd({
                fid : this.fid,
                type,
                fcId : this.list[this.chapterNum].fictionChapterId,
                num : this.list[this.chapterNum].chapterNum,
            }).then(res => {
                if(res.code == 200){
                    this.getFictionShelfList()
                    if(typeof fn == 'function'){
                        fn()
                    }
                }
            })
        },
    }
}
</script>

<style lang="less" scoped>
.bookRead{
    position: relative;
    height: 100%;
    width: 100%;
    overflow: hidden;
}
/* 上菜单栏 */
.bounceTop{
    position: absolute;
    top: 0;
    left: 0;
    height: 60px;
    width: 100%;
    z-index: 99;
    display: flex;
}
.bounceTop .arrow-left{
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 40px;
}
.bounceTop .right{
    position: absolute;
    right: 10px;
    top: 0;
    height: 100%;
    display: flex;
}
.bounceTop .right>div{
    height: 100%;
    width: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0 10px;
}

.bounceTop .addBookshelfRead{
    text-align: center;
    color: #fff;
    height: 40px;
    line-height: 40px;
    position: absolute;
    right: 0;
    top: 100px;
    width: 100px;
    border-top-left-radius: 20px;
    border-bottom-left-radius: 20px;
}

/* 下菜单栏 */
.bounceBottom{
    position: absolute;
    bottom: 0;
    left: 0;
    height: 90px;
    width: 100%;
    z-index: 99;
}
.bounceBottom .top{
    display: flex;
    justify-content: center;
    align-items: center;
    height: 40px;
    line-height: 40px;
    font-size: 15px;
}
.bounceBottom .bottom{
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    height: calc(~'100% - 40px');
    line-height: 50px;
    font-size: 15px;
    width: 100%;
}
.bounceBottom .bottom > div{
    width: 50%;
    height: 100%;
}
.bounceBottom .top>div{
    width: calc(~'100% - 160px');
    margin: 0 20px;
}

.bounceTop-enter-active{
    animation: bounceTop 0.5s;
}
.bounceTop-leave-active{
    animation: bounceTop 0.5s reverse;
}
.bounceBottom-enter-active{
    animation: bounceBottom 0.5s;
}
.bounceBottom-leave-active{
    animation: bounceBottom 0.5s reverse;
}
@keyframes bounceTop {
    0%{
        transform: translate(0, -60px);
    }
    100%{
        transform: translate(0, 0);
    }
}
@keyframes bounceBottom {
    0%{
        transform: translate(0, 80px);
    }
    100%{
        transform: translate(0, 0);
    }
}


.fictionChaptersTitle{
    width: 100%;
    height: 40px;
    line-height: 40px;
    text-align: center;
    overflow: hidden;
    font-size: 15px;
}
.fictionChapters{
    width: 100%;
    height: calc(~'100% - 40px');
    /* overflow-y: scroll;
    overflow-x: hidden; */
}

.TTS{
    position: fixed;
    left: 0;
    top: 0;
    height: 100vh;
    width: 100vw;
    z-index: 999;
    .TTSboxBottom{
        position: absolute;
        bottom: 0;
        left: 0;
        height: 220px;
        width: 100%;
        color: #fff;
        background-color: rgba(0, 0, 0, 0.8);
        .TTSend{
            position: absolute;
            bottom: 0;
            left: 0;
            font-size: 16px;
            height: 50px;
            width: 100%;
            line-height: 50px;
            text-align: center;
            border-top: 1px solid #fff;
        }
        .TTS-line{
            padding: 20px;
            font-size: 16px;
        }
        .pers{
            color: #fff;
            display: flex;
            div{
                flex: 1;
                padding: 10px 0;
                text-align: center;
                border-radius: 10px;
                border: 1px solid #999;
                box-sizing: border-box;
                margin: 5px;
            }
            .active{
                background-color: lightseagreen;
            }
        }
        
    }
}
</style>